# -*- coding: utf-8 -*-
"""
@Author: Rengar
@e-mail: rengar.fan@amutec.cn
@Date: 2024/4/23 
@Desc:
"""

import logging
import os
from multiprocessing import Process
from os import path

from colorlog import ColoredFormatter
from concurrent_log_handler import ConcurrentRotatingFileHandler

PROJECT_PATH = path.dirname(path.abspath(__file__)).replace('\\', '/')  # 当前文件路径
DEFAULT_LOG_PATH = path.join(PROJECT_PATH, 'out/logs').replace('\\', '/')
if not os.path.exists(DEFAULT_LOG_PATH):
    os.makedirs(DEFAULT_LOG_PATH)
log_file_path = DEFAULT_LOG_PATH
SIMPLE_FORMAT = "%(levelname)s: %(message)s"
simple_format = logging.Formatter(SIMPLE_FORMAT)

FILE_FORMAT = '%(asctime)s - "%(pathname)s:%(lineno)d" - %(levelname)s - %(message)s'
file_formatter = logging.Formatter(fmt=FILE_FORMAT)

# 默认的format 彩色
STANDARD_FORMAT = '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
standard_formatter = logging.Formatter(fmt=STANDARD_FORMAT)

# 创建一个ColoredFormatter对象
colored_formatter = ColoredFormatter(
    '%(log_color)s%(pathname)s:%(lineno)d %(log_color)s%(asctime)s - '
    '%(log_color)s%(levelname)s - %(log_color)s%(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
    log_colors={
        'DEBUG': 'white',
        'INFO': 'green',
        'WARNING': 'yellow',
        'ERROR': 'red',
        'CRITICAL': 'bold_red',
    },

)

# -----------------------------------------
# 根据自己的需求自定义handler

# file handler  轮转文件日志
file_name = "amat.txt"
file_path = f"{DEFAULT_LOG_PATH}/{file_name}"
maxBytes = 1024 * 1024 * 20  # 20M
backupCount = 14  # 保留7份

# 多进程支持
file_handler = ConcurrentRotatingFileHandler(file_path, maxBytes=maxBytes, backupCount=backupCount,
                                             encoding="utf-8")
# file_handler = RotatingFileHandler(file_path, maxBytes=maxBytes, backupCount=backupCount, encoding="utf-8")
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(file_formatter)

# console_handle 只在控制台打印的彩色日志
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(colored_formatter)

# -----------------------------------------
# 不直接调用_log
_log = logging.getLogger("amat")
_log.addHandler(file_handler)
_log.addHandler(console_handler)
_log.setLevel(logging.DEBUG)


# -----------------------------------------
# 增加tag字段
class Log:

    @staticmethod
    def log(self, level, msg, *args, **kwargs):
        return _log.log(self, level, msg, *args, **kwargs)

    @staticmethod
    def setLevel(level):
        _log.setLevel(level)

    @staticmethod
    def addHandler(handler):
        _log.addHandler(handler)

    @staticmethod
    def _tag(tag="", message=""):
        if tag and tag != "":

            msg = f"{tag} {message}"
        else:
            msg = message

        return msg

    # 请勿随意更改stack_level,除非需要增加
    @staticmethod
    def info(tag="", message="", stack_level=2, *args, **kwargs):
        msg = Log._tag(tag, message)
        if "stacklevel" not in kwargs:
            kwargs['stacklevel'] = stack_level  # 确保在真正调用的地方打印log
        _log.info(msg, *args, **kwargs)

    @staticmethod
    def debug(tag="", message="", stack_level=2, *args, **kwargs):
        msg = Log._tag(tag, message)
        if "stacklevel" not in kwargs:
            kwargs['stacklevel'] = stack_level  # 确保在真正调用的地方打印log
        _log.debug(msg, *args, **kwargs)

    @staticmethod
    def error(tag="", message="", stack_level=2, *args, **kwargs):
        msg = Log._tag(tag, message)
        if "stacklevel" not in kwargs:
            kwargs['stacklevel'] = stack_level  # 确保在真正调用的地方打印log
        _log.error(msg, *args, **kwargs)

    @staticmethod
    def warning(tag="", message="", stack_level=2, *args, **kwargs):
        msg = Log._tag(tag, message)
        if "stacklevel" not in kwargs:
            kwargs['stacklevel'] = stack_level  # 确保在真正调用的地方打印log
        _log.warning(msg, *args, **kwargs)

    @staticmethod
    def critical(tag="", message="", stack_level=2, *args, **kwargs):
        msg = Log._tag(tag, message)
        if "stacklevel" not in kwargs:
            kwargs['stacklevel'] = stack_level  # 确保在真正调用的地方打印log
        _log.critical(msg, *args, **kwargs)

    @staticmethod
    def exception(tag="", msg="", stack_level=2, *args, exc_info=True, **kwargs):
        msg = Log._tag(tag, msg)
        if "stacklevel" not in kwargs:
            kwargs['stacklevel'] = stack_level  # 确保在真正调用的地方打印log
        _log.exception(msg, *args, exc_info=exc_info, **kwargs)

    @staticmethod
    def handle(record):
        _log.handle(record)

    @staticmethod
    def removeHandler(handler_):
        _log.removeHandler(handler_)

    @staticmethod
    def hasHandlers():
        return _log.hasHandlers()

    @staticmethod
    def callHandlers(record):
        _log.callHandlers(record)

    @staticmethod
    def getEffectiveLevel():
        _log.getEffectiveLevel()

    @staticmethod
    def isEnabledFor(level):
        return _log.isEnabledFor(level)

    @staticmethod
    def getChild(suffix):
        return _log.getChild(suffix)

    @staticmethod
    def findCaller(stack_info=False, stacklevel=1):
        return _log.findCaller(stack_info=stack_info, stacklevel=stacklevel)

    @staticmethod
    def makeRecord(name, level, fn, lno, msg, args, exc_info,
                   func=None, extra=None, sinfo=None):

        return _log.makeRecord(name, level, fn, lno, msg, args, exc_info,
                               func=func, extra=extra, sinfo=sinfo)


def my_test_log():
    Log.info('my test log')


if __name__ == '__main__':
    # Log.setLevel(logging.DEBUG)
    # Log.info("这是一条info信息")
    processes = []
    for i in range(10):
        p = Process(target=my_test_log)
        processes.append(p)
        p.start()

    for p in processes:
        p.join()
